#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MCP 配置文件生成器

这个脚本可以帮助用户快速生成各种MCP客户端的配置文件，包括：
- Claude Desktop 配置
- Cursor 配置
- 自定义客户端配置
- 开发环境配置
- 生产环境配置
"""

import json
import os
import sys
from typing import Dict, List, Optional, Any
from pathlib import Path
import argparse
from datetime import datetime

class MCPConfigGenerator:
    """MCP配置生成器类"""
    
    def __init__(self):
        self.config_templates = {
            "claude_desktop": self._claude_desktop_template,
            "cursor": self._cursor_template,
            "custom": self._custom_template,
            "development": self._development_template,
            "production": self._production_template
        }
    
    def _claude_desktop_template(self, services: List[Dict]) -> Dict:
        """Claude Desktop 配置模板"""
        config = {
            "mcpServers": {}
        }
        
        for service in services:
            server_name = service.get("name", "unknown-server")
            config["mcpServers"][server_name] = {
                "command": service.get("command", "python"),
                "args": service.get("args", ["main.py"])
            }
            
            # 添加可选配置
            if service.get("env"):
                config["mcpServers"][server_name]["env"] = service["env"]
            
            if service.get("cwd"):
                config["mcpServers"][server_name]["cwd"] = service["cwd"]
        
        return config
    
    def _cursor_template(self, services: List[Dict]) -> Dict:
        """Cursor 配置模板"""
        config = {
            "mcp": {
                "servers": {}
            }
        }
        
        for service in services:
            server_name = service.get("name", "unknown-server")
            config["mcp"]["servers"][server_name] = {
                "command": service.get("command", "python"),
                "args": service.get("args", ["main.py"])
            }
            
            # 添加可选配置
            if service.get("env"):
                config["mcp"]["servers"][server_name]["env"] = service["env"]
            
            if service.get("cwd"):
                config["mcp"]["servers"][server_name]["cwd"] = service["cwd"]
        
        return config
    
    def _custom_template(self, services: List[Dict]) -> Dict:
        """自定义配置模板"""
        config = {
            "version": "1.0",
            "created": datetime.now().isoformat(),
            "servers": {}
        }
        
        for service in services:
            server_name = service.get("name", "unknown-server")
            config["servers"][server_name] = {
                "command": service.get("command", "python"),
                "args": service.get("args", ["main.py"]),
                "transport": service.get("transport", "stdio"),
                "timeout": service.get("timeout", 30),
                "restart": service.get("restart", True)
            }
            
            # 添加可选配置
            if service.get("env"):
                config["servers"][server_name]["env"] = service["env"]
            
            if service.get("cwd"):
                config["servers"][server_name]["cwd"] = service["cwd"]
            
            if service.get("description"):
                config["servers"][server_name]["description"] = service["description"]
        
        return config
    
    def _development_template(self, services: List[Dict]) -> Dict:
        """开发环境配置模板"""
        config = self._custom_template(services)
        
        # 开发环境特定设置
        config["environment"] = "development"
        config["debug"] = True
        config["logging"] = {
            "level": "DEBUG",
            "file": "mcp_debug.log"
        }
        
        # 为所有服务添加开发环境设置
        for server_name, server_config in config["servers"].items():
            server_config["timeout"] = 60  # 更长的超时时间
            server_config["restart"] = True
            server_config["env"] = server_config.get("env", {})
            server_config["env"]["DEBUG"] = "1"
            server_config["env"]["PYTHONPATH"] = "."
        
        return config
    
    def _production_template(self, services: List[Dict]) -> Dict:
        """生产环境配置模板"""
        config = self._custom_template(services)
        
        # 生产环境特定设置
        config["environment"] = "production"
        config["debug"] = False
        config["logging"] = {
            "level": "INFO",
            "file": "mcp_production.log",
            "rotation": "daily"
        }
        
        # 为所有服务添加生产环境设置
        for server_name, server_config in config["servers"].items():
            server_config["timeout"] = 30
            server_config["restart"] = True
            server_config["health_check"] = {
                "enabled": True,
                "interval": 60
            }
        
        return config
    
    def generate_config(self, template_type: str, services: List[Dict], 
                       output_file: Optional[str] = None) -> str:
        """生成配置文件
        
        Args:
            template_type: 配置模板类型
            services: 服务列表
            output_file: 输出文件路径
            
        Returns:
            生成的配置JSON字符串
        """
        if template_type not in self.config_templates:
            raise ValueError(f"不支持的模板类型: {template_type}")
        
        # 生成配置
        template_func = self.config_templates[template_type]
        config = template_func(services)
        
        # 格式化JSON
        config_json = json.dumps(config, indent=2, ensure_ascii=False)
        
        # 保存到文件
        if output_file:
            os.makedirs(os.path.dirname(output_file), exist_ok=True)
            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(config_json)
        
        return config_json
    
    def generate_service_definition(self, name: str, command: str, args: List[str],
                                  cwd: Optional[str] = None, env: Optional[Dict] = None,
                                  description: Optional[str] = None) -> Dict:
        """生成服务定义
        
        Args:
            name: 服务名称
            command: 启动命令
            args: 命令参数
            cwd: 工作目录
            env: 环境变量
            description: 服务描述
            
        Returns:
            服务定义字典
        """
        service = {
            "name": name,
            "command": command,
            "args": args
        }
        
        if cwd:
            service["cwd"] = cwd
        
        if env:
            service["env"] = env
        
        if description:
            service["description"] = description
        
        return service
    
    def validate_config(self, config_file: str) -> List[str]:
        """验证配置文件
        
        Args:
            config_file: 配置文件路径
            
        Returns:
            验证错误列表
        """
        errors = []
        
        try:
            with open(config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
        except FileNotFoundError:
            return [f"配置文件不存在: {config_file}"]
        except json.JSONDecodeError as e:
            return [f"JSON格式错误: {str(e)}"]
        
        # 检查基本结构
        if "mcpServers" in config:  # Claude Desktop 格式
            servers = config["mcpServers"]
        elif "mcp" in config and "servers" in config["mcp"]:  # Cursor 格式
            servers = config["mcp"]["servers"]
        elif "servers" in config:  # 自定义格式
            servers = config["servers"]
        else:
            return ["配置文件缺少服务器定义"]
        
        # 验证每个服务器
        for server_name, server_config in servers.items():
            if not isinstance(server_config, dict):
                errors.append(f"服务器 '{server_name}' 配置必须是对象")
                continue
            
            # 检查必需字段
            if "command" not in server_config:
                errors.append(f"服务器 '{server_name}' 缺少 'command' 字段")
            
            if "args" not in server_config:
                errors.append(f"服务器 '{server_name}' 缺少 'args' 字段")
            elif not isinstance(server_config["args"], list):
                errors.append(f"服务器 '{server_name}' 的 'args' 必须是数组")
            
            # 检查工作目录
            if "cwd" in server_config:
                cwd = server_config["cwd"]
                if not os.path.exists(cwd):
                    errors.append(f"服务器 '{server_name}' 的工作目录不存在: {cwd}")
            
            # 检查环境变量
            if "env" in server_config:
                if not isinstance(server_config["env"], dict):
                    errors.append(f"服务器 '{server_name}' 的 'env' 必须是对象")
        
        return errors

def create_sample_configs():
    """创建示例配置文件"""
    generator = MCPConfigGenerator()
    
    # 示例服务定义
    services = [
        generator.generate_service_definition(
            name="greeting-server",
            command="python",
            args=["main.py"],
            cwd="/path/to/greeting-server",
            description="简单的问候服务器"
        ),
        generator.generate_service_definition(
            name="file-server",
            command="python",
            args=["-m", "file_server"],
            env={"DEBUG": "1"},
            description="文件操作服务器"
        )
    ]
    
    # 生成各种配置
    configs = {
        "claude_desktop.json": generator.generate_config("claude_desktop", services),
        "cursor_config.json": generator.generate_config("cursor", services),
        "custom_config.json": generator.generate_config("custom", services),
        "development.json": generator.generate_config("development", services),
        "production.json": generator.generate_config("production", services)
    }
    
    return configs

def main():
    """命令行主函数"""
    parser = argparse.ArgumentParser(description="MCP配置文件生成器")
    parser.add_argument("--type", "-t", 
                       choices=["claude_desktop", "cursor", "custom", "development", "production"],
                       default="custom",
                       help="配置模板类型")
    parser.add_argument("--output", "-o", help="输出文件路径")
    parser.add_argument("--validate", "-v", help="验证配置文件")
    parser.add_argument("--sample", "-s", action="store_true", help="生成示例配置")
    
    args = parser.parse_args()
    
    generator = MCPConfigGenerator()
    
    if args.validate:
        # 验证配置文件
        errors = generator.validate_config(args.validate)
        if errors:
            print("配置验证失败:")
            for error in errors:
                print(f"  - {error}")
            sys.exit(1)
        else:
            print("配置验证通过")
            sys.exit(0)
    
    if args.sample:
        # 生成示例配置
        configs = create_sample_configs()
        for filename, config_content in configs.items():
            print(f"\n=== {filename} ===")
            print(config_content)
        sys.exit(0)
    
    # 交互式生成配置
    print("MCP配置生成器")
    print("===============")
    
    services = []
    
    while True:
        print("\n添加MCP服务:")
        name = input("服务名称: ").strip()
        if not name:
            break
        
        command = input("启动命令 [python]: ").strip() or "python"
        args_input = input("命令参数 [main.py]: ").strip() or "main.py"
        args = [arg.strip() for arg in args_input.split()]
        
        cwd = input("工作目录 (可选): ").strip() or None
        description = input("服务描述 (可选): ").strip() or None
        
        # 环境变量
        env = None
        env_input = input("环境变量 (格式: KEY1=value1,KEY2=value2, 可选): ").strip()
        if env_input:
            env = {}
            for pair in env_input.split(','):
                if '=' in pair:
                    key, value = pair.split('=', 1)
                    env[key.strip()] = value.strip()
        
        service = generator.generate_service_definition(
            name=name,
            command=command,
            args=args,
            cwd=cwd,
            env=env,
            description=description
        )
        
        services.append(service)
        
        if input("\n继续添加服务? (y/N): ").strip().lower() != 'y':
            break
    
    if not services:
        print("未添加任何服务")
        sys.exit(1)
    
    # 生成配置
    try:
        config_json = generator.generate_config(args.type, services, args.output)
        
        if args.output:
            print(f"\n配置已保存到: {args.output}")
        else:
            print("\n生成的配置:")
            print(config_json)
    
    except Exception as e:
        print(f"生成配置失败: {str(e)}")
        sys.exit(1)

if __name__ == "__main__":
    main()